#pragma once
#include <memory>
#include <functional>
#include "fields.hpp"
#include "detail.hpp"

namespace bitrpc
{
    // 消息的抽象类
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {}
        // 设置消息id
        virtual void setId(const std::string &id)
        {
            _rid = id;
        }
        // 获取消息id
        virtual std::string rid()
        {
            return _rid;
        }
        // 设置消息类型
        virtual void setMType(MType mtype)
        {
            _mtype = mtype;
        }
        // 获取消息类型
        virtual MType mtype()
        {
            return _mtype;
        }

        virtual std::string serialize() = 0;                  // 序列化
        virtual bool unserialize(const std::string &msg) = 0; // 反序列化
        virtual bool check() = 0;                             // 反序列化后校验

    private:
        MType _mtype;
        std::string _rid;
    };

    // 缓冲区的抽象类
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        // 缓冲区数据的个数
        virtual size_t readableSize() = 0;

        // 尝试从缓冲区读取一个int32_t(4字节)类型的数据，没有删除！！！
        virtual int32_t peekInt32() = 0;

        // 删除缓冲区一个int32_t(4字节)类型的数据
        virtual void retriveInt32() = 0;

        // 从缓冲区读取一个int32_t(4字节)类型的数据并删除缓冲区的这4字节数据
        virtual int32_t readInt32() = 0;

        // 从缓冲区取出指定长度的数据
        virtual std::string retrieveAsString(size_t length) = 0;
    };

    // 协议的抽象类
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;
        // 是否能够处理该消息
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;
        // 处理消息
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;
        // 将消息序列化
        virtual std::string serialize(const BaseMessage::ptr &msg) = 0;
    };

    // 连接的抽象类
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        // 发送消息
        virtual void send(const BaseMessage::ptr &msg) = 0;
        // 关闭连接
        virtual void shutdown() = 0;
        // 连接是否是正常的
        virtual bool connected() = 0;
    };
    // 连接成功的回调函数
    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    // 连接断开的回调函数
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    // 消息的回调函数
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;
    // 服务器的抽象类
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        // 设置连接成功的回调函数
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            //ELOG("设置连接成功的回调函数!");
            _cb_connection = cb;
        }
        // 设置连接断开的回调函数
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            //ELOG("设置连接断开的回调函数!");
            _cb_close = cb;
        }
        // 设置消息的回调函数
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            //ELOG("设置消息的回调函数!");
            _cb_message = cb;
        }
        // 启动服务器
        virtual void start() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    // 客户端的抽象类
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        // 设置连接成功的回调函数
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            //ELOG("设置连接成功的回调函数!");
            _cb_connection = cb;
        }
        // 设置连接断开的回调函数
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            //ELOG("设置连接断开的回调函数!");
            _cb_close = cb;
        }
        // 设置消息的回调函数
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            //ELOG("设置消息的回调函数!");
            _cb_message = cb;
        }
        // 连接服务器
        virtual void connect() = 0;
        // 关闭连接
        virtual void shutdown() = 0;
        // 发送消息
        virtual bool send(const BaseMessage::ptr &msg) = 0;
        // 获取连接对象
        virtual BaseConnection::ptr connection() = 0;
        // 连接是否是正常的
        virtual bool connected() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

}